<template>
  <div class="video-preview-dialog" v-if="visible">
    <div class="dialog-wrapper">
      <div class="dialog-header">
        <h3>{{ title || '实时视频预览' }}</h3>
        <span class="close-btn" @click="handleClose">&times;</span>
      </div>
      <div class="dialog-body">
        <div class="video-dbclick-container" @dblclick="handleDoubleClick"></div>
        <div class="video-container" :id="videoPlayerId">
          <div v-if="loading" class="video-loading">
            <div class="loading-spinner"></div>
            <div class="loading-text">视频加载中...</div>
          </div>
          <div v-if="error" class="video-error">
            <i class="error-icon">!</i>
            <div class="error-text">视频加载失败</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import EZUIKit from 'ezuikit-js'
import { ref, onMounted, onUnmounted, computed, watch } from 'vue'
import { getEzvizToken } from '@/api/auth'

// 定义组件属性
const props = defineProps<{
  visible: boolean;
  title?: string;
  cameraInfo: {
    name: string;
    deviceSerial: string;
    channelNo: number;
    status: 'online' | 'offline' | 'error';
    [key: string]: any;
  };
  showInfo?: boolean;
}>()

// 定义组件事件
const emit = defineEmits<{
  (e: 'close'): void;
  (e: 'error', error: any): void;
}>()

// 播放器状态
const loading = ref(true)
const error = ref(false)
const player = ref<any>(null)
const accessToken = ref('')
const videoPlayerId = 'preview_video_player'
const url = ref('')

// 计算属性：状态文本
const statusText = computed(() => {
  return props.cameraInfo.status === 'online' ? '在线' :
    props.cameraInfo.status === 'offline' ? '离线' : '异常'
})

// 获取萤石云Token
const fetchEzvizToken = async () => {
  try {
    const res = await getEzvizToken()
    if (res && res.code === '0' && res.data) {
      accessToken.value = res.data
      return res.data
    } else {
      console.error('获取萤石云Token失败:', res)
      return null
    }
  } catch (error) {
    console.error('获取萤石云Token异常:', error)
    return null
  }
}

// 初始化视频播放器
const initPlayer = async () => {
  try {
    loading.value = true
    error.value = false

    // 先获取token
    const token = await fetchEzvizToken()
    if (!token) {
      throw new Error('无法获取萤石云访问令牌')
    }

    // 组装播放地址: ezopen://open.ys7.com/设备序列号/通道号.hd.live
    url.value = `ezopen://open.ys7.com/${props.cameraInfo.deviceSerial}/${props.cameraInfo.channelNo}.hd.live`

    // 确保EZUIKit已加载
    if (typeof EZUIKit === 'undefined') {
      console.error('萤石云SDK未加载，请确保已引入相关脚本')
      loading.value = false
      error.value = true
      return
    }

    // 确保DOM元素渲染完成
    let retryCount = 0;
    const maxRetries = 5;
    const checkElement = () => {
      // 检查DOM元素是否存在
      const videoElement = document.getElementById(videoPlayerId)
      if (!videoElement) {
        if (retryCount < maxRetries) {
          retryCount++;
          console.log(`视频DOM元素 ${videoPlayerId} 未准备好，等待... (${retryCount}/${maxRetries})`)
          setTimeout(checkElement, 200);
        } else {
          console.error(`视频DOM元素 ${videoPlayerId} 不存在，超过最大重试次数`)
          loading.value = false
          error.value = true
        }
        return;
      }

      console.log(`视频DOM元素 ${videoPlayerId} 已准备好，初始化播放器`)
      // 创建播放器实例
      try {
        player.value = new EZUIKit.EZUIKitPlayer({
          id: videoPlayerId,
          url: url.value,
          template: "pcLive",
          plugin: ["talk"],
          accessToken: token
        })

        // 设置错误处理
        player.value.handleError = (e: any) => {
          console.error('播放器错误:', e)
          loading.value = false
          error.value = true
          emit('error', e)
        }

        // 播放成功后隐藏加载状态
        setTimeout(() => {
          loading.value = false
        }, 1000)
      } catch (err) {
        console.error('创建播放器实例失败:', err)
        loading.value = false
        error.value = true
        emit('error', err)
      }
    }

    // 开始检查DOM元素
    checkElement();

  } catch (e) {
    console.error('初始化视频播放器失败:', e)
    loading.value = false
    error.value = true
    emit('error', e)
  }
}

const handleFullscreenChange = () => {
  if (!document.fullscreenElement) {
    // 退出全屏时重新设置播放器
    setTimeout(() => {
      try {
        // 检查元素是否仍存在
        if (!document.getElementById(videoPlayerId)) {
          console.warn('视频元素已不存在，无法重新初始化')
          return
        }

        // 重新设置视频容器尺寸
        if (player.value) {
          player.value.destroy() // 销毁原有播放器实例

          // 重新初始化播放器
          const newPlayer = new EZUIKit.EZUIKitPlayer({
            id: videoPlayerId,
            url: url.value,
            template: "pcLive",
            plugin: ["talk"],
            accessToken: accessToken.value
          })

          // 更新播放器引用
          player.value = newPlayer
        }
      } catch (error) {
        console.error('退出全屏重建播放器失败:', error)
      }
    }, 100)

    // 移除监听器
    document.removeEventListener('fullscreenchange', handleFullscreenChange)
  }
}

// 添加全屏变化监听
document.addEventListener('fullscreenchange', handleFullscreenChange)

// 销毁播放器
const destroyPlayer = () => {
  if (player.value) {
    try {
      player.value.stop()
      player.value = null
    } catch (e) {
      console.error('销毁播放器失败:', e)
    }
  }
}

// 关闭弹窗
const handleClose = () => {
  destroyPlayer()
  emit('close')
}

// 当组件挂载后立即执行初始化
onMounted(() => {
  console.log('VideoPreviewDialog 组件已挂载')
  if (props.visible) {
    console.log('组件挂载时 visible 为 true，准备初始化播放器')
    // 给DOM一些时间渲染
    setTimeout(() => {
      initPlayer()
    }, 500)
  }
})

// 监听visible属性变化
watch(() => props.visible, (newVal, oldVal) => {
  console.log('visible 属性变化:', oldVal, '->', newVal)
  if (newVal) {
    // 弹窗打开时初始化播放器
    console.log('visible 变为 true，准备初始化播放器')
    setTimeout(() => {
      initPlayer()
    }, 500)
  } else {
    // 弹窗关闭时销毁播放器
    console.log('visible 变为 false，销毁播放器')
    destroyPlayer()
  }
}, { immediate: true })

// 组件卸载时清理
onUnmounted(() => {
  destroyPlayer()
})

// 在 script setup 部分添加双击全屏功能
const handleDoubleClick = () => {
  const videoContainer = document.getElementById('preview_video_player')
  if (!document.fullscreenElement) {
    videoContainer?.requestFullscreen()
  } else {
    document.exitFullscreen()
  }
}
</script>

<style scoped>
.video-preview-dialog {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  z-index: 999;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: fadeIn 0.3s;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

.dialog-wrapper {
  width: calc(100vw - 960px);
  height: 75%;
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
  animation: scaleIn 0.3s;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  max-width: 1200px;
  min-width: 600px;
}

@keyframes scaleIn {
  from {
    transform: translate(-50%, -50%) scale(0.9);
  }

  to {
    transform: translate(-50%, -50%) scale(1);
  }
}

.dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 20px;
  background: #151515;
}

.dialog-header h3 {
  margin: 0;
  font-size: 16px;
  color: #fff;
  font-weight: 500;
}

.close-btn {
  cursor: pointer;
  font-size: 20px;
  color: #fff;
  transition: all 0.3s;
  width: 24px;
  height: 24px;
  line-height: 24px;
  text-align: center;
  border-radius: 50%;
}

.close-btn:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.2);
}

.dialog-body {
  flex: 1;
  display: flex;
  overflow: hidden;
  position: relative;
}

.video-container {
  flex: 1;
  height: 100%;
  background: #000;
  cursor: pointer;
}

.video-dbclick-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 100;
}

.video-loading,
.video-error {
  position: absolute;
  top: 40px;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.8);
  z-index: 20;
}

.loading-spinner {
  width: 50px;
  height: 50px;
  border: 4px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  border-top-color: #fff;
  animation: spin 1s ease-in-out infinite;
  margin-bottom: 15px;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.loading-text,
.error-text {
  color: #fff;
  font-size: 16px;
}

.error-icon {
  width: 50px;
  height: 50px;
  line-height: 50px;
  text-align: center;
  border-radius: 50%;
  background: #ff4d4f;
  color: #fff;
  font-size: 32px;
  font-style: normal;
  margin-bottom: 15px;
}

@media (max-width: 768px) {
  .dialog-wrapper {
    width: 95%;
    height: 80%;
  }
}
</style>